package misc;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;


public class XMLManager{
	public static Document writeXMLDocument(XMLRootElement xml){
		try{
			DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
			Document xmlDocument = docBuilder.newDocument();
			
			Element rootElement = xmlDocument.createElement(xml.getName());
			xmlDocument.appendChild(rootElement);
			
			XMLElement[] xmlElements = xml.getXmlElements();
			for(int i=0; i<xmlElements.length; i++){
				populateXML(xmlDocument, rootElement, xmlElements[i]);
			}
			
			return xmlDocument;
			
		}catch(ParserConfigurationException e){
			e.printStackTrace();
		}
		
		return null;
	}
	
	private static void populateXML(Document doc, Element rootElement, XMLElement xmlElement){
		Element element = doc.createElement(xmlElement.getName());
		
		XMLAttribute[] xmlAttributes = xmlElement.getXmlAttributes();
		if(xmlAttributes != null){
			for(int i=0; i<xmlAttributes.length; i++){
				element.setAttribute(xmlAttributes[i].getName(), xmlAttributes[i].getValue());
			}
		}
		
		XMLElement[] xmlElementsNested = xmlElement.getXmlElements();
		if(xmlElementsNested != null){
			for(int i=0; i<xmlElementsNested.length; i++){
				populateXML(doc, element, xmlElementsNested[i]);
			}
		}
		
		String value = xmlElement.getValue();
		if(value != null){
			element.appendChild(doc.createTextNode(value));
		}
		
		rootElement.appendChild(element);
	}
	
	public static HashMap<String, String> readXMLDocument(Document xmlDocument){
		HashMap<String, String> hm = new HashMap<String, String>();
		Node node = xmlDocument.getFirstChild();
		check(node, hm);
		
		return hm;
	}
	
	private static void check(Node node, HashMap<String, String> hm){
		while(node != null){
			if(node.getNodeName() != null && !node.getNodeName().startsWith("#")){
				hm.put(node.getNodeName(), node.getTextContent());
			}if(node.hasChildNodes()){
				check(node.getFirstChild(), hm);
			}
			node = node.getNextSibling();
		}
	}
	
	public static boolean saveXMLFile(Document doc, File xmlFile){		
		try{
			StreamResult result = new StreamResult(xmlFile);
			
			TransformerFactory transformerFactory = TransformerFactory.newInstance();
			Transformer transformer = transformerFactory.newTransformer();
			
			DOMSource source = new DOMSource(doc);
			transformer.transform(source, result);
			
			return true;
			
		}catch(TransformerConfigurationException e){
			e.printStackTrace();
		}catch(TransformerException e){
			e.printStackTrace();
		}
		
		return false;
	}
	
	public static Document loadXMLFile(File xmlFile){
		try{
			DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder docBuilder = docFactory.newDocumentBuilder();			
			Document xmlDocument = docBuilder.parse(xmlFile);
			
			return xmlDocument;
			
		}catch(ParserConfigurationException e){
			e.printStackTrace();
		}catch(SAXException e){
			e.printStackTrace();
		}catch(IOException e){
			e.printStackTrace();
		}
		
		return null;
	}	
}